﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace AutoCompleteText
{
    class Automata
    {
        public static int STATE_1 = 1;
        public static int STATE_2 = 2;
        public static int STATE_3 = 3;
        public static int STATE_4 = 4;
        public static int STATE_5 = 5;
        public static int STATE_6 = 6;
        public static int STATE_7 = 7;
        public static int STATE_8 = 8;
        public static int STATE_9 = 9;
        public static int STATE_0 = 0;
        public static int CurrentState=0;

        public List<int> stackState = new List<int>();

        public String ingWord="";		// 작성중 글자
        public String completeText="";	// 완성 문자열
        char prevChar;
        public Automata()
        {
          
        }
        public void BackState ()
        {
            CurrentState = stackState[stackState.Count -1 ];
            stackState.RemoveAt( stackState.Count - 1 );
        }
        public void CurrentStateReset ()
        {
            CurrentState = 0;
        }

        public int getIngWordLength()
        {
            return this.ingWord.Length;
        }
        public void removeIngWord()
        {
            if(ingWord.Length!=0)
            {

                ingWord = ingWord.Remove(ingWord.Length - 1, 1);
            }
            return;
        }
        public void ClearCompleteText()
        {
            ingWord = "";
            completeText = "";
        }
        public void removeIngCompleteText()
        {
            if (completeText.Length != 0)
            {
                completeText = completeText.Remove(completeText.Length - 1, 1);
            }
            return;

        }
        public int getCombineSize()
        {
            if (ingWord.Length != 0)
                return this.completeText.Length + 1;


            Console.WriteLine("BufferSize Complete = " + completeText.Length + ",  ing size = " + ingWord.Length);
            return this.completeText.Length;
        }
        public String getCombineAll(String str)
        {
            //if(completeText.Length == 0)
            //{
            //    Console.WriteLine("complete size " + completeText.Length);
            //    return getCombineString(str);
            //}
            //return getCombineString(str) + ingWord;
            return getCombineString(str) + PrintCombine(ingWord );

        }
        public String getCombineString(String str)
        {
            //str = str + " ";
            try
            {
                foreach (char c in str)
                {
                    AutomataStateMachine(c);
                }
            }catch(Exception e)
            {
                Console.WriteLine(e.StackTrace);

            }

            Console.WriteLine("complete size " + completeText.Length);
            Console.WriteLine("complete " + completeText);
         //   Console.WriteLine("ingword " + ingWord + "gggg");
            return completeText;
        }
        


        public void AutomataStateMachine(char inputChar)
        {
            if(inputChar.Equals(" "))
            {
                Console.WriteLine("스페이스 완료 출력 " + PrintCombine(ingWord));
                CurrentState = STATE_0;
            }
            
            //현재 상태가 0일 경우
            if(CurrentState==0)
            {
                
                //처음 들어온 글자가 자음일 경우
                if (CheckConsontantVowel(inputChar) == 1)
                {

                    ingWord += inputChar.ToString();
                    CurrentState = STATE_1;
                    
                }
                else
                {   //모음일 경우

                    ingWord += inputChar.ToString();
                    CurrentState = STATE_2;
                    
                }
            }else if(CurrentState==1)
            {
                //현재 상태가 1일경우
                if (CheckConsontantVowel(inputChar) == 1)
                {   //자음일 경우
                    //C1S1
                    completeText += PrintCombine(ingWord);
                    Console.WriteLine("C1S1 출력 " + PrintCombine(ingWord));
                    ingWord = inputChar.ToString();
                    CurrentState = STATE_1;

                }
                else
                {   //모음일 경우



                    ingWord += inputChar.ToString();
                    CurrentState = STATE_3;

                }

            }else if(CurrentState==2)
            {
                if (CheckConsontantVowel(inputChar) == 1)
                {   //자음일 경우
                    //C2S1
                    ingWord+=inputChar;
                    completeText += PrintCombine(ingWord);
                    Console.WriteLine("C2S1 출력 " + PrintCombine(ingWord));
                    
                    CurrentState = STATE_1;

                }
                else if(CheckVc(inputChar))
                {   //복모음일 경우

                   // ingWord += inputChar;


                    CurrentState = STATE_4;

                }else if(CheckV(inputChar))
                {
                    //C2S2
                    completeText += PrintCombine(ingWord);
                    Console.WriteLine("C2S2 출력 " + PrintCombine(ingWord));

                    ingWord = inputChar.ToString();
                    CurrentState = STATE_2;
                }

            }
            else if (CurrentState == 3)
            {
                if (CheckT(inputChar))
                {

                    ingWord += inputChar;
                    CurrentState = STATE_5;

                }
                else if (CheckL(inputChar))
                {
                    completeText += PrintCombine(ingWord);
                    Console.WriteLine("C3S1 출력 " + PrintCombine(ingWord));
                    ingWord = inputChar.ToString();
                    CurrentState = STATE_1;
                }
                else if (CheckVc(inputChar))
                {
                    ingWord += inputChar;
                    CurrentState = STATE_6;
                    ReplaceVc(inputChar,1);
                }else if(CheckV(inputChar))
                {
                    completeText += PrintCombine(ingWord);
                    Console.WriteLine("C3S2출력 " + PrintCombine(ingWord));
                    ingWord = inputChar.ToString();
                    CurrentState = STATE_2;
                }
            }
            else if (CurrentState == 4)
            {
                if(CheckConsontantVowel(inputChar)==1)
                {
                    //C4S1
                    completeText += PrintCombine(ingWord);
                    Console.WriteLine("C4S1 출력 " + PrintCombine(ingWord));
                    ingWord = inputChar.ToString();
                    CurrentState = STATE_1;
                }else if(CheckConsontantVowel(inputChar)==-1)
                {
                    //C4S2
                    ReplaceVc(inputChar, 0);
                    completeText += PrintCombine(ingWord);
                    Console.WriteLine("C4S2 출력 " + PrintCombine(ingWord));
                    ingWord = inputChar.ToString();
                    CurrentState = STATE_2;
                }
            }
            else if (CurrentState == 5)
            {
                if(CheckTc(inputChar))
                {
                    ingWord += inputChar;
                    CurrentState = STATE_7;

                }else if(CheckL(inputChar))
                {
                    completeText += PrintCombine(ingWord);
                    Console.WriteLine("C5S1 출력 " + PrintCombine(ingWord));
                    ingWord = inputChar.ToString();
                    CurrentState = STATE_1;

                }else if(CheckConsontantVowel(inputChar)==-1)
                {
                    String tmpStr = ingWord[0].ToString() + ingWord[1].ToString();
                    ingWord = ingWord[2].ToString() + inputChar.ToString();
                    completeText += PrintCombine(tmpStr);
                    Console.WriteLine("C3S3 출력 " + PrintCombine(tmpStr));
                    
                    CurrentState = STATE_3;

                }
            }
            else if (CurrentState == 6)
            {
                if(CheckT(inputChar))
                {
                    ingWord += inputChar;
                    CurrentState = STATE_8;

                }else if(CheckL(inputChar))
                {
                    completeText += PrintCombine(ingWord);
                    Console.WriteLine("C6S1 출력 " + PrintCombine(ingWord));
                    ingWord = inputChar.ToString();
                    CurrentState = STATE_1;
                }else if(CheckConsontantVowel(inputChar)==-1)
                {
                    ingWord = ingWord.Remove(2, 1);
                    completeText += PrintCombine(ingWord);
                    Console.WriteLine("C6S2 출력 " + PrintCombine(ingWord));
                    ingWord = inputChar.ToString();
                    CurrentState = STATE_2;
                }
            }

            else if (CurrentState == 7)
            {
                if(CheckConsontantVowel(inputChar)==1)
                {
                    ReplaceTc(inputChar, 1);
                    completeText += PrintCombine(ingWord);
                    Console.WriteLine("C7S1 출력 " + PrintCombine(ingWord));
                    ingWord = inputChar.ToString();
                    CurrentState = STATE_1;
                }else if(CheckConsontantVowel(inputChar)==-1)
                {

                    String tmpStr = ingWord[0].ToString() + ingWord[1].ToString() + ingWord[2].ToString();
                    ingWord = ingWord[3].ToString() + inputChar.ToString();
                    completeText += PrintCombine(tmpStr);
                    Console.WriteLine("C5S3 출력 " + PrintCombine(tmpStr));

                    CurrentState = STATE_3;
                }
            }
            else if (CurrentState == 8)
            {
                if(CheckTc(inputChar))
                {
                    ingWord += inputChar;
                    CurrentState = STATE_9;

                }else if(CheckL(inputChar))
                {
                    completeText += PrintCombine(ingWord);
                    Console.WriteLine("C8S1 출력 " + PrintCombine(ingWord));
                    ingWord = inputChar.ToString();
                    CurrentState = STATE_1;

                }else if(CheckConsontantVowel(inputChar)==-1)
                {
                    
                    String tmpStr = ingWord[0].ToString() + ingWord[1].ToString();
                    ingWord = ingWord[2].ToString() + inputChar.ToString();

                    completeText += PrintCombine(tmpStr);
                    Console.WriteLine("C6S3 출력 " + PrintCombine(tmpStr));

                    CurrentState = STATE_3;
                }
            }
            else if (CurrentState == 9)
            {
                if(CheckConsontantVowel(inputChar)==1)
                {
                    ReplaceTc(inputChar, 1);
                    completeText += PrintCombine(ingWord);
                    Console.WriteLine("C9S1 출력 " + PrintCombine(ingWord));
                    ingWord = inputChar.ToString();
                    CurrentState = STATE_1;

                }else if(CheckConsontantVowel(inputChar)==-1)
                {
                    String tmpStr = ingWord[0].ToString() + ingWord[1].ToString() + ingWord[2].ToString();
                    ingWord = ingWord[3].ToString() + inputChar.ToString();
                    completeText += PrintCombine(tmpStr);
                    Console.WriteLine("C8S3 출력 " + PrintCombine(tmpStr));

                    CurrentState = STATE_3;

                }
            }

            stackState.Add(CurrentState);
            prevChar = inputChar;
        }
        public String PrintCombine(String inputStr)
        {
            Console.WriteLine("automata = " + inputStr);
            inputStr = inputStr.Replace(" ", "");
            
            char outChar = new char();
            switch (inputStr.Length)
            {
                case 0:
                    break;
                case 1:

                    outChar = Convert.ToChar(inputStr);
                    break;
                case 2:
                    HangulAnalyzer.Merge(Convert.ToChar(inputStr.Substring(0, 1))
                        , Convert.ToChar(inputStr.Substring(1, 1)), out outChar);
                    break;
                case 3:
                    HangulAnalyzer.Merge(Convert.ToChar(inputStr.Substring(0, 1))
                        , Convert.ToChar(inputStr.Substring(1, 1)),
                        Convert.ToChar(inputStr.Substring(2, 1)), out outChar);
                    break;
            }
            return outChar.ToString();

        }
        public void ClearBuffer()
        {
            if (CurrentState == 2)
            {
                this.ingWord = "";
            }

        }
        //초성 체크하기
        public bool CheckL(char inputChar)
        {
            if (HangulAnalyzer.chosung.IndexOf(inputChar.ToString()) != -1)
            {
                return true;
            }
            return false;
        }

        //중성 - 복모음 체크하기(이전값을 이용함)
        public void ReplaceVc(char inputChar, int mode)
        {
       
            switch (prevChar)
            {
                case 'ㅗ':
                    if (inputChar == 'ㅏ')
                    {

                        ingWord=ingWord.Replace('ㅗ', 'ㅘ');
                        if (mode == 1) ingWord = ingWord.Remove(2, 1);
                    }
                    else if (inputChar == 'ㅐ')
                    {
                        ingWord=ingWord.Replace('ㅗ', 'ㅙ');
                        if (mode == 1) ingWord = ingWord.Remove(2, 1);
                    }
                    else if (inputChar == 'ㅣ')
                    {

                        ingWord=ingWord.Replace('ㅗ', 'ㅚ');
                        if (mode == 1) ingWord = ingWord.Remove(2, 1);
                    }
                    break;
                case 'ㅜ':
                    if (inputChar == 'ㅓ')
                    {
                       ingWord=  ingWord.Replace('ㅜ', 'ㅝ');
                       if (mode == 1) ingWord = ingWord.Remove(2, 1);
                    }else if(inputChar == 'ㅔ')
                    {
                        ingWord=ingWord.Replace('ㅜ', 'ㅞ');
                        if (mode == 1) ingWord = ingWord.Remove(2, 1);
                    }else if(inputChar == 'ㅣ')
                    {
                        ingWord=ingWord.Replace('ㅜ', 'ㅟ');
                        if (mode == 1) ingWord = ingWord.Remove(2, 1);
                    }
                    break;
                case 'ㅡ':
                    if (inputChar == 'ㅣ')
                    {
                        ingWord=ingWord.Replace('ㅡ', 'ㅣ');
                        if (mode == 1) ingWord = ingWord.Remove(2, 1);
                    }
                    break;
            }
        }

       
        public bool CheckVc(char inputChar)
        {
            switch(prevChar)
            {
                case 'ㅗ':
                    if (inputChar == 'ㅏ')
                    {
                        
                     // ingWord=  ingWord.Replace('ㅗ'.ToString(), "ㅘ");
                        return true;
                    }else if(inputChar == 'ㅐ')
                    {

                    //    ingWord=ingWord.Replace('ㅗ'.ToString(), "ㅙ");
                        return true;
                    }else if(inputChar == 'ㅣ')
                    {

                    //    ingWord=ingWord.Replace('ㅗ'.ToString(), "ㅚ");
                        return true;
                    }
                    break;
                case 'ㅜ':
                    if (inputChar == 'ㅓ' || inputChar == 'ㅔ' || inputChar == 'ㅣ')
                    {
                        return true;
                    }
                    break;
                case 'ㅡ':
                    if (inputChar == 'ㅣ')
                    {
                        return true;
                    }
                    break;
            }
            return false;
        }

        //중성 - 모음 체크하기(이전값을 이용함)
        public bool CheckV(char inputChar)
        {
            switch (prevChar)
            {
                case 'ㅗ':
                    if (inputChar == 'ㅏ' || inputChar == 'ㅐ' || inputChar == 'ㅣ')
                    {
                        return false;
                    }
                    break;
                case 'ㅜ':
                    if (inputChar == 'ㅓ' || inputChar == 'ㅔ' || inputChar == 'ㅣ')
                    {
                        return false;
                    }
                    break;
                case 'ㅡ':
                    if (inputChar == 'ㅣ')
                    {
                        return false;
                    }
                    break;
            }
            if(HangulAnalyzer.jungsung.IndexOf(inputChar.ToString())!=-1)
            {
                return true;
            }

            return false;
        }
        
        public void ReplaceTc(char inputChar, int mode)
        {
            switch (ingWord[2])
            {
                case 'ㄱ':
                    if (ingWord[3] == 'ㅅ')
                    {
                        ingWord = ingWord.Replace(ingWord[2], 'ㄳ');
                        if (mode == 1) ingWord = ingWord.Remove(3, 1);
                    }   
                    break;
                case 'ㄴ':
                    if (ingWord[3] == 'ㅈ')
                    {
                        ingWord = ingWord.Replace(ingWord[2], 'ㄵ');
                        if (mode == 1) ingWord=ingWord.Remove(3, 1);
                    }
                    else if (ingWord[3] == 'ㅎ')
                    {
                        ingWord = ingWord.Replace(ingWord[2], 'ㄶ');
                        if (mode == 1) ingWord=ingWord.Remove(3, 1);
                    }
                    break;
                case 'ㄹ':
                    if (ingWord[3] == 'ㄱ')
                    {
                        ingWord = ingWord.Replace(ingWord[2], 'ㄺ');
                        if (mode == 1) ingWord=ingWord.Remove(3, 1);
                    }
                    else if (ingWord[3] == 'ㅁ')
                    {
                        ingWord = ingWord.Replace(ingWord[2], 'ㄻ');
                        if (mode == 1) ingWord=ingWord.Remove(3, 1);
                    }
                    else if (ingWord[3] == 'ㅂ')
                    {
                        ingWord = ingWord.Replace(ingWord[2], 'ㄼ');
                        if (mode == 1) ingWord=ingWord.Remove(3, 1);
                    }
                    else if (ingWord[3] == 'ㅅ')
                    {
                        ingWord = ingWord.Replace(ingWord[2], 'ㄽ');
                        if (mode == 1) ingWord=ingWord.Remove(3, 1);
                    }
                    else if (ingWord[3] == 'ㅌ')
                    {
                        ingWord = ingWord.Replace(ingWord[2], 'ㄾ');
                        if (mode == 1) ingWord=ingWord.Remove(3, 1);
                    }
                    else if (ingWord[3] == 'ㅍ')
                    {
                        ingWord = ingWord.Replace(ingWord[2], 'ㄿ');
                        if (mode == 1) ingWord=ingWord.Remove(3, 1);
                    }
                    else if (ingWord[3] == 'ㅎ')
                    {
                        ingWord = ingWord.Replace(ingWord[2], 'ㅀ');
                        if (mode == 1) ingWord=ingWord.Remove(3, 1);
                    }
                    break;
                case 'ㅂ':
                    if (ingWord[3] == 'ㅅ')
                    {
                        ingWord = ingWord.Replace(ingWord[2], 'ㅄ');
                        if (mode == 1) ingWord=ingWord.Remove(3, 1);
                    }
                    break;
            }
            
        }
        //종성 - 복자음 체크하기(이전값을 이용함)
        public bool CheckTc(char inputChar)
        {
            switch (prevChar)
            {
                case 'ㄱ':
                    if (inputChar == 'ㅅ')
                    {
                        return true;
                    }
                    break;
                case 'ㄴ':
                    if (inputChar == 'ㅈ' || inputChar == 'ㅎ')
                    {
                        return true;
                    }
                    break;
                case 'ㄹ':
                    if (inputChar == 'ㄱ' || inputChar == 'ㅁ' || inputChar == 'ㅂ'
                        || inputChar == 'ㅅ' || inputChar == 'ㅌ' 
                        || inputChar == 'ㅍ' || inputChar == 'ㅎ')
                    {
                        return true;
                    }
                    break;
                case 'ㅂ':
                    if (inputChar == 'ㅅ')
                    {
                        return true;
                    }
                    break;
            }
            return false;
        }
        //종성 - 자음 체크하기(이전값을 이용함)
        public bool CheckT(char inputChar)
        {
            switch (prevChar)
            {
                case 'ㄱ':
                    if (inputChar == 'ㅅ')
                    {
                        return false;
                    }
                    break;
                case 'ㄴ':
                    if (inputChar == 'ㅈ' || inputChar == 'ㅎ')
                    {
                        return false;
                    }
                    break;
                case 'ㄹ':
                    if (inputChar == 'ㄱ' || inputChar == 'ㅁ' || inputChar == 'ㅂ'
                        || inputChar == 'ㅅ' || inputChar == 'ㅌ'
                        || inputChar == 'ㅍ' || inputChar == 'ㅎ')
                    {
                        return false;
                    }
                    break;
                case 'ㅂ':
                    if (inputChar == 'ㅅ')
                    {
                        return false;
                    }
                    break;
            }
            if (HangulAnalyzer.jongsung.IndexOf(inputChar.ToString()) != -1)
            {
                return true;
            }
            return false;
        }
        //자음일경우 리턴1, 모음이면 -1, 이 외값은 0;
        public int CheckConsontantVowel(char inputChar)
        {

            if (HangulAnalyzer.chosung.IndexOf(inputChar.ToString()) != -1)
            {
               
                return 1;
            }
            else if (HangulAnalyzer.jungsung.IndexOf(inputChar.ToString()) != -1)
            {
                
                return -1;
            }
            return 0;

        }
     
    }

}
